#include <ani.h>
#include <array>
#include <iostream>

static void testBigInt([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object num)
{
    ani_class bigIntCls;
    const char * className = "escompat.BigInt";
    if (ANI_OK != env->FindClass(className, &bigIntCls)) {
        std::cerr << "Not found '" << className << "'" << std::endl;
        return ;
    }
    ani_method getLongMethod;
    if (ANI_OK != env->Class_FindMethod(bigIntCls, "getLong", ":l", &getLongMethod)){
        std::cerr << "Class_GetMethod Failed '" << className << "'" << std::endl;
        return ;
    }

    ani_long longnum;
    if (ANI_OK != env->Object_CallMethod_Long(num, getLongMethod, &longnum)){
        std::cerr << "Object_CallMethod_Long '" << "getLongMethod" << "'" << std::endl;
        return ;
    }
    std::cout << "num value is : '" << longnum << "'" << std::endl;
    return;
}

ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
{
    ani_env *env;
    if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
        std::cerr << "Unsupported ANI_VERSION_1" << std::endl;
        return ANI_ERROR;
    }

    static const char *className = "ani_bigint.Foo";
    ani_class cls;
    if (ANI_OK != env->FindClass(className, &cls)) {
        std::cerr << "Not found '" << className << "'" << std::endl;
        return ANI_ERROR;
    }

    std::array methods = {
        ani_native_function {"testBigInt", "C{escompat.BigInt}:", reinterpret_cast<void *>(testBigInt)},
    };
    std::cout << "Start bind native methods to '" << className << "'" << std::endl;

    if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) {
        std::cerr << "Cannot bind native methods to '" << className << "'" << std::endl;
        return ANI_ERROR;
    };
    std::cout << "Finish bind native methods to '" << className << "'" << std::endl;

    *result = ANI_VERSION_1;
    return ANI_OK;
}